// Copyright 2006 Bret Taylor
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.

#include "astprinter.h"

namespace indie {

AstPrinter::AstPrinter() : Visitor(), stream_(NULL), num_tabs_(0) {
}

AstPrinter::~AstPrinter() {
}

void AstPrinter::Print(const Ast& ast, ostream& stream) {
    stream_ = &stream;
    num_tabs_ = 0;
    ast.Accept(*this);
    stream_ = NULL;
    num_tabs_ = 0;
}

void AstPrinter::Enter(const AstClassType& ast) {
    PrintNode("ClassType");
}

void AstPrinter::Enter(const AstArrayType& ast) {
    PrintNode("ArrayType");
}

void AstPrinter::Enter(const AstUnionType& ast) {
    PrintNode("UnionType");
}

void AstPrinter::Enter(const AstVariable& ast) {
    PrintNode("Variable");
}

void AstPrinter::Enter(const AstMethod& ast) {
    PrintNode("Method");
}

void AstPrinter::Enter(const AstClass& ast) {
    PrintNode("Class");
}

void AstPrinter::Enter(const AstFile& ast) {
    PrintNode("File");
}

void AstPrinter::Enter(const AstBlockStatement& ast) {
    PrintNode("BlockStatement");
}

void AstPrinter::Enter(const AstExpressionStatement& ast) {
    PrintNode("ExpressionStatement");
}

void AstPrinter::Enter(const AstAssignment& ast) {
    PrintNode("Assignment");
}

void AstPrinter::Enter(const AstVariableDeclaration& ast) {
    PrintNode("VariableDeclaration");
}

void AstPrinter::Enter(const AstEmptyStatement& ast) {
    PrintNode("EmptyStatement");
}

void AstPrinter::Enter(const AstIf& ast) {
    PrintNode("If");
}

void AstPrinter::Enter(const AstWhile& ast) {
    PrintNode("While");
}

void AstPrinter::Enter(const AstFor& ast) {
    PrintNode("For");
}

void AstPrinter::Enter(const AstBreak& ast) {
    PrintNode("Break");
}

void AstPrinter::Enter(const AstReturn& ast) {
    PrintNode("Return");
}

void AstPrinter::Enter(const AstParenthesizedExpression& ast) {
    PrintNode("ParenthesizedExpression");
}

void AstPrinter::Enter(const AstAccess& ast) {
    PrintNode("Access");
}

void AstPrinter::Enter(const AstArrayAccess& ast) {
    PrintNode("ArrayAccess");
}

void AstPrinter::Enter(const AstBinaryExpression& ast) {
    PrintNode("BinaryExpression");
}

void AstPrinter::Enter(const AstUnaryExpression& ast) {
    PrintNode("UnaryExpression");
}

void AstPrinter::Enter(const AstCall& ast) {
    PrintNode("Call");
}

void AstPrinter::Enter(const AstNewInstance& ast) {
    PrintNode("NewInstance");
}

void AstPrinter::Enter(const AstNewArray& ast) {
    PrintNode("NewArray");
}

void AstPrinter::Enter(const AstTypeTest& ast) {
    PrintNode("TypeTest");
}

void AstPrinter::Enter(const AstThis& ast) {
    PrintNode("This");
}

void AstPrinter::Enter(const AstIntegerConstant& ast) {
    PrintNode("IntegerConstant");
}

void AstPrinter::Enter(const AstStringConstant& ast) {
    PrintNode("StringConstant");
}

void AstPrinter::Enter(const AstFloatConstant& ast) {
    PrintNode("FloatConstant");
}

void AstPrinter::Enter(const AstBooleanConstant& ast) {
    PrintNode("BooleanConstant");
}

void AstPrinter::LeaveDefault(const Ast& ast) {
    num_tabs_--;
}

void AstPrinter::PrintNode(const char* node_type) {
    for (unsigned int i = 0; i < num_tabs_; i++) {
	*stream_ << "  ";
    }
    *stream_ << node_type << std::endl;
    num_tabs_++;
}

} // namespace indie
